﻿using Aliphant.Mvvm.XEvent.Interface;
using Aliphant.Mvvm.XEvent.Models;
using System.Windows.Controls;
using System.Xml.Linq;

namespace Aliphant.Mvvm.XEvent.Ioc
{
    public class XContainerImpl : IXContainer
    {
        private IDictionary<string, object> _serviceRegistry = new Dictionary<string, object>();
        private IDictionary<string, object> _navigationRegistry = new Dictionary<string, object>();

        public void Register<TService>() where TService : class, new()
        {
            _serviceRegistry[typeof(TService).Name] = new TService();
        }

        public void Register<TService>(string name) where TService : class, new()
        {
            _serviceRegistry[name] = new TService();
        }

        public void Register<TService>(Func<TService> factory) where TService : class
        {
            _serviceRegistry[typeof(TService).Name] = factory;
        }

        public void RegisterNavigation<TService>(string name) where TService : class, new()
        {
            _navigationRegistry[name] = new TService();
        }

        public void RegisterRegion<TService>(TService region, string regionName) where TService : class, new()
        {
            _serviceRegistry[regionName] = region;
        }


        public TService Resolve<TService>() where TService : class, new()
        {
            if (_serviceRegistry.ContainsKey(typeof(TService).Name))
            {
                var service = (TService)_serviceRegistry[typeof(TService).Name];
                return service;
            }
            else
            {
                throw new InvalidOperationException($"No service of type {typeof(TService).Name} has been registered.");
            }
        }

        public TService Resolve<TService>(string name) where TService : class, new()
        {
            if (_serviceRegistry.ContainsKey(name))
            {
                var service = (TService)_serviceRegistry[name];
                return service;
            }
            else
            {
                throw new InvalidOperationException($"No service of type {typeof(TService).Name} has been registered.");
            }
        }

        public void NavigateTo(string region, string name, NavigateParameter navigateParameter)
        {
            if (_serviceRegistry.ContainsKey(region) && _navigationRegistry.ContainsKey(name))
            {
                var regionObj = _serviceRegistry[region];
                var navigationObj = _navigationRegistry[name];

                if (regionObj is ContentControl content)
                {
                    content.Content = navigationObj;
                    if (navigationObj is UserControl userControl)
                    {
                        if (userControl.DataContext is INavigate navigateVM)
                        {
                            navigateVM.OnNavigateTo(navigateParameter);
                        }
                    }

                }
            }
        }

        public void NavigateTo(string region, string name)
        {
            NavigateTo(region, name, new NavigateParameter());
        }

        public void CancelRegister(string name)
        {
            if (_serviceRegistry.ContainsKey(name))
            {
                _serviceRegistry.Remove(name);
            }
        }
    }
}
